package com.shilei.spring.util;

import com.shilei.spring.Test;
import com.shilei.spring.annotation.Component;
import com.shilei.spring.annotation.LogAuto;
import com.shilei.spring.annotation.Refresh;
import com.shilei.spring.annotation.Value;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author 石雷
 * shilei1@jiayuan.com
 * 2021/8/26/026 11:08
 */
public class BeanUtil {

    public static Map<String,Object> beans=new HashMap<>();
    public static Set<String> valueClass=new HashSet<>();
    public static Map<String,Map<String,Object>> kv=new HashMap<>();

    public static void initBeans(String pack)  {
        Set<Class<?>> classes = PackageUtil.getClasses(pack);
        System.out.println("**初始化bean 开始**");
        for(Class c:classes){
            // 获取有Component 的类
            if(c.isAnnotationPresent(Component.class)||c.isAnnotationPresent(LogAuto.class)){
                try {
                    beans.put(c.getName(),c.newInstance());
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                System.out.println("初始化"+c.getName());
            }
        }
        System.out.println("**初始化bean 结束**");
    }

    /**
     * 获取所有带@value注解的类
     * @return
     */
    public static void getValues(String pack){
        Set<Class> annotations = new HashSet<>();
        annotations.add(Refresh.class);

        Set<Class<?>> classes = AnnotationUtil.getClassByAnnotation(pack, annotations);
        for (Class<?> c : classes) {
            Object o = beans.get(c.getName());
            if(o==null){
                System.out.println("ERROR "+c.getName()+" 需要 @Component!!!!!");
            }else{
                /**
                 * 反射获类
                 */
                Class<?> clazz = o.getClass();
                /**
                 * 获取类中所有属性
                 */
                Field[] fields = clazz.getDeclaredFields();
                Map<String, Object> map = new HashMap<>();
                for (Field field : fields) {
                    if(field.isAnnotationPresent(Value.class)){
                        valueClass.add(clazz.getName());
                        Value[] annotationsByType = field.getAnnotationsByType(Value.class);
                        for (Value value : annotationsByType) {
                            String properValue = PropertiesUtil.getValue(value.key());
                            //私有方法 设置可访问不然反射操作报错
                            field.setAccessible(true);
                            try {
                                field.set(o, properValue);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }

                            map.put(field.getName(),properValue);
                            kv.put(clazz.getName(),map);

                        }
                    }
                }
            }
        }
    }
    public static void DI(String pack){
        try {
            System.out.println("==注入value 开始==");
            for (Map.Entry<String, Map<String, Object>> entry : kv.entrySet()) {
                String beanName = entry.getKey();
                Object o = beans.get(beanName);
                Map<String, Object> value = entry.getValue();
                for (Map.Entry<String, Object> objectEntry : value.entrySet()) {
                    Field field = null;
                    try {
                        field = o.getClass().getDeclaredField(objectEntry.getKey());
                    } catch (NoSuchFieldException e) {
                    } catch (SecurityException e) {
                    }
                    if(field==null){
                        field = o.getClass().getSuperclass().getDeclaredField(objectEntry.getKey());
                    }

                    //私有方法 设置可访问不然反射操作报错
                    field.setAccessible(true);
                    field.set(o,objectEntry.getValue());
                    System.out.println(field.getName()+":"+objectEntry.getValue());
                }


            }
            System.out.println("==注入value 结束==");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static  <T> T getBean(Class<T> clazz){
        Object o = beans.get(clazz.getName());
        if(clazz.isInstance(o)){
            return clazz.cast(o);
        }
        return null;
    }
    public static void setBean(String beanName,Object bean){
        beans.put(beanName,bean);
    }
}
